                    MACHINE LANGUAGE PART VII

                 by Lyle Giese (LYLEG on DELPHI)


It looks like this month we will finish up the Sequential File Reader.
So what will I do next month? Let me know what YOU want written about. I
really want to write about something that will interest you, and the
best way to do that is to tell me! My DELPHI username is LYLEG, and if
you are on Genie tell deb! and she will forward the comments to me.

When we left off last month we just opened the file to be read and now
are ready to decide if we want to send it to the printer or the screen.
Of course, we first print a message to the screen asking Screen or
Printer?

In line 1280, we get a character from the keyboard (if there is one,
remember this routine will a CHR$(0) if there are no keys pressed). We
check for an "s" for the screen. If we found one we JSR to the screen
setup routine. If not we check for a "p".

Let's look at the 'OSCR' subroutine starting at line 6500. Why are we
opening a logical file for the screen? Doesn't the Programmers Reference
Guide say it is not needed? Yes, that is true. But our output routine
will need to be able to send to the screen or the printer. The printer
needs the logical file to be there. So it can be easier to send the
output to a logical file rather that decide for each character how to
send it, depending on the output device selected.

Of course, we could have written two output routines. Then every time we
sent a character, we would have to check and see which output device was
selected and branch to the proper routine.

Ok, now if we want to send our file to our printer we will go to line
6000 for the PRINTER subroutine. There we ask what device number we are
going to use. Here (in lines 6060-6090) we limit the device number to 4
through 7. After we get the device number we convert it from PETSCII to
the number we must use for the SETLFS routine.

Next we can select the secondary address within the limits zero to nine.
I limited myself to this range to make the routines here simple. Again,
we have to convert from PETSCII to the number to be used for the SETLFS
routine.

Now we can open the logical file. For a printer channel, we don't need a
file name and set the length of the filename to zero and finally JSR
OPEN. Why don't we check the printer file the same way we did the disk
file?

Well, first of all, nothing has been sent to the printer yet. Until we
open the output channel (JSR CHKOUT) the secondary address and the
listen commands are not sent. At that time is when we find out if the
printer is not there, when the program hangs up (depending on the
printer and interface).

Finally we are getting to the heart of the whole thing! Read a character
and send it to our output device. First (in line 1400-1410) we open an
input channel to the disk drive. And then we try to get our first
character from the disk drive.

Some of CBM's DOS routines (depending on the type of drive) will send
several null bytes before sending the first byte of the file, and here
we trap them. Next we must store that character as we must read the
status byte and store it also.

Now here is where I made the routine "generic", by loading up the byte
representing the outfile and opening an output channel to it. At this
point we could care less if the output device was the screen, printer or
even a disk drive (of course we would have to write a different
subroutine for opening an output file on the disk drive.)

In line 1490, we are checking for a successful opening of the output
channel. If the channel is not openning, I do a CLRCHN (restore default
I/O) and try again. Why? I had quite a bit of trouble with this routine
locking up when sending a file to my printer until I put lines 1490-1530
in.

It seems that my printer interface could not keep up with the rapid
opening and closing of channels on the serial bus. It would miss the JSR
CHKOUT in line 1480 once in a while. Then in line 1550, CHROUT assumes
the channel is properly opened and will crash your program.

This one place where the PRG misses an important point. If you look at
the description of CHROUT on page 278-279 (of the PRG for the C-64),
they miss that little detail. And of course I put in a way to break out
of this loop in case the printer realy wasn't there (lines 1510-1530).

Now is the time to check the status byte we stored in line 1460. At this
point we are only interested in the end of file bit and use the AND
instruction to look at only that bit. If it is not set we will continue
on as we have not reached the end of the file yet.

I decided that it would be nice to be able to pause the output in order
to take time to read the contents of the screen before it scrolls out of
sight. Or a way to abort out if we found out this file was not the one
we really wanted to look at or if we wanted to just see what the file
contained.

I used the SHFLAG byte at $028D to see if the Shift key is pressed. This
byte is updated by the systems normal IRQ routines. If the shift key
only is down this byte holds a value of 1. If the CTRL key is down, a 4
is placed there. And if the logo key is down a 2 is found here. If 2 or
more of these keys are depressed the sum of the key values is found
there at $028D.

As long as the shift key is down (or shift lock), the program will go
into a loop rechecking the SHFLAG byte. If the Shift and Control keys
are down (for a value of 6), then abort out just as if we hit the end of
the file.

In line 1650 we jump back to and get another byte for outputting.

Now when we finish we have to start closing channels and logical files
in line 1680. We have to close the read file before the disk command
channel. In this program, it is not as important. But if we were writing
to a disk file and closed the command file, that would close ALL open
files in the drive, even if we didn't want them closed yet.

Next we go after the printer (or screen). On some printers, incoming
characters are buffered until the buffer is full or a carriage return is
received. So here we send a carriage return to make sure the buffer is
emptyed before we close up.

Now a message is printed to tell us to press the return key before the
program is allowed to start over, which clears the screen. There (if you
remember) hitting the return with no character in our filename buffer
will exit this program.

And that concludes our file reader finally! Next month??? You tell me.
PLEASE!

Lyle Giese
AKA LYLEG

[ED. NOTE: This is LYLEG'S final article in his multi-part series on a
Sequential File Reader.  Included in this issue of the *StarBoard*
Journal is the full PAL source code and the object code.  Load Object
Code,8,1 and then SYS49152 to use. If you haven't been following along
for the last few months, be sure to go back and retrieve his earlier
articles.  They are excellent!
